package datos;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.Vector;

import modelo.Administrador;
import modelo.Aula;
import modelo.Equipo;
import modelo.Hardware;
import modelo.Software;
import modelo.Solicitud;
import modelo.Tecnico;
import modelo.TipoHard;
import modelo.Usuario;

public class CentroBD extends AccesoBD{

	public Hashtable<String, Usuario> obtenerUsuarios() throws SQLException{
		if (this.getConexion()==null){
			return null;
		}
		Hashtable<String, Usuario> usuarios = new Hashtable<String, Usuario>();
		ResultSet rs_u = lanzarSelect("SELECT * FROM USUARIOS");
		while (rs_u.next()){
			if (rs_u.getString(5).equalsIgnoreCase("usu")){
				Usuario usu = new Usuario(rs_u.getString(1), rs_u.getString(2), rs_u.getString(3), rs_u.getString(4),
																			rs_u.getString(6));
				usuarios.put(rs_u.getString(1), usu);
			}else if(rs_u.getString(5).equalsIgnoreCase("tec")){
				Tecnico tec = new Tecnico(rs_u.getString(1), rs_u.getString(2), rs_u.getString(3), rs_u.getString(4),
						rs_u.getString(6));
				usuarios.put(rs_u.getString(1), tec);
			}else{
				Administrador admin = new Administrador(rs_u.getString(1), rs_u.getString(2), rs_u.getString(3), rs_u.getString(4),
						rs_u.getString(6));
				usuarios.put(rs_u.getString(1), admin);
			}
		}
		return usuarios;
	}
	
	public void crearUsuario(Usuario usuario) throws SQLException{
		if (this.getConexion()==null){
			return;
		}
		String tipo = null;
		if (usuario.getClass().getName().substring(usuario.getClass().getName().lastIndexOf(".")+1).equalsIgnoreCase("usuario")){
			tipo = "usu";
		}else if (usuario.getClass().getName().substring(usuario.getClass().getName().lastIndexOf(".")+1).equalsIgnoreCase("tecnico")){
			tipo = "tec";
		}else{
			tipo = "admin";
		}
		lanzarInsert("USUARIOS", "(idUSUARIOS,NOMBRE,APELLIDOS,EMAIL,ROL,PASSWORD)", "('"+usuario.getIdUsuario()+"','"+usuario.getNombre()+"','"+usuario.getApellidos()+"','"+usuario.getEmail()+"','"+tipo+"','"+usuario.getPassword()+"')");
	}
	
	public Vector<Aula> obtenerAulas() throws SQLException{
		if (this.getConexion()==null){
			return null;
		}
		Vector<Aula> vAulas = new Vector<Aula>();
		ResultSet rs_a = lanzarSelect("SELECT * FROM AULAS");
		while (rs_a.next()){
			Vector<Equipo> vEqAula = new Vector<Equipo>();
			ResultSet rs_eqAu = lanzarSelect("SELECT * FROM EQUIPOS WHERE AULA_idAULA='"+rs_a.getString(1)+"'");
			while (rs_eqAu.next()){
				Equipo equipo = new Equipo(rs_eqAu.getString(1), rs_eqAu.getString(2));
				if (!equipo.getIdEquipo().equals("-1")){
					vEqAula.addElement(equipo);
				}
			}
			Aula aula = new Aula(rs_a.getString(1), rs_a.getInt(2), vEqAula);
			if(!aula.getIdAula().equals("-1")){
				vAulas.addElement(aula);
			}
		}
		return vAulas;	
	}
	
	public void crearAula(Aula aula) throws SQLException{
		if (this.getConexion()==null){
			return;
		}
		lanzarInsert("AULAS", "(idAula,capacidad)", "('"+aula.getIdAula()+"',"+aula.getCapacidad()+")");
		for (int i=0;i<aula.getvEquipos().size();i++){
			Equipo equipo = aula.getvEquipos().elementAt(i);
			equipo.setCodAula(aula.getIdAula());
			modificarEquipo(equipo);
		}
	}
	
	public void modificarAula(Aula aula) throws SQLException{
		if (this.getConexion()==null){
			return;
		}
		lanzarUpdate("AULAS", "idAULA='" + aula.getIdAula() + "'," + "capacidad=" + aula.getCapacidad(),"idAula=" + aula.getIdAula());
		if (aula.getvEquipos()!=null || aula.getvEquipos().size()!=0){
			for(int i=0;i<aula.getvEquipos().size();i++){
				lanzarUpdate("EQUIPOS", "AULA_idAULA='"+aula.getIdAula()+"'", "idEQUIPOS='"+aula.getvEquipos().elementAt(i).getIdEquipo()+"'");
			}
		}
	}

	/**
	 * Devuelve true si el aula tiene equipos asignados.
	 * @param aula el aula que se quiere comprobar
	 * @return true si el aula tiene equipos
	 * @throws SQLException
	 */
	public boolean tieneEquipos(Aula aula) throws SQLException{
		if (this.getConexion()==null){
			return false;
		}
		ResultSet rs = lanzarSelect("SELECT * FROM EQUIPOS WHERE AULA_idAULA='"+aula.getIdAula()+"'");
		while (rs.next()){
			return true;
		}
		return false;
	}
	
	/**
	 * Obtiene todos los equipos de la BD
	 * @return Devuelve un vector con todos los equipos
	 * @throws SQLException
	 */
	public Vector<Equipo> obtenerEquipos() throws SQLException{
		if (this.getConexion()==null){
			return null;
		}
		Vector<Equipo> vEquipos = new Vector<Equipo>();
		ResultSet rs_e = lanzarSelect("SELECT * FROM EQUIPOS");
		while (rs_e.next()){
			Vector<Hardware> vEqHard = new Vector<Hardware>();
			Vector<Software> vEqSoft = new Vector<Software>();
			Equipo equipo = new Equipo(rs_e.getString(1),rs_e.getString(2));
			ResultSet rs_eqhard = lanzarSelect("SELECT * FROM HARDWARE WHERE idHARDWARE IN (SELECT idHARD FROM EQHARD WHERE idEQUIPO='"+equipo.getIdEquipo()+"')");
			while (rs_eqhard.next()){
				Hardware hardware = new Hardware(rs_eqhard.getString(1), rs_eqhard.getString(2), rs_eqhard.getString(3), rs_eqhard.getString(4));
				vEqHard.addElement(hardware);
			}
			ResultSet rs_eqsoft = lanzarSelect("SELECT * FROM SOFTWARE WHERE idSOFTWARE IN (SELECT idSOFTWARE FROM EQSOFT WHERE idEQ='"+equipo.getIdEquipo()+"')");
			while (rs_eqsoft.next()){
				Software software = new Software(rs_eqsoft.getString(1), rs_eqsoft.getString(2), rs_eqsoft.getString(3));
				vEqSoft.addElement(software);
			}
			if(!equipo.getIdEquipo().equals("-1")){
				Equipo eq = new Equipo(rs_e.getString(1), rs_e.getString(2), rs_e.getString(3), vEqHard, vEqSoft);
				vEquipos.addElement(eq);
			}
		}
		return vEquipos;
	}
	
	public void crearEquipo(Equipo equipo) throws SQLException{
		if (this.getConexion()==null){
			return;
		}
		lanzarInsert("EQUIPOS", "(idEquipos,IP,AULA_idAula)","('"+equipo.getIdEquipo()+"','"+equipo.getIp()+"','"+equipo.getCodAula()+"')");
		for (int i=0;i<equipo.getvHardwares().size();i++){
			lanzarInsert("EQHARD", "(idHard,idEquipo)", "('"+equipo.getvHardwares().elementAt(i).getIdHardware()+"','"+equipo.getIdEquipo()+"')");
		}
		if (equipo.getvSoftwares()!=null || equipo.getvSoftwares().size()!=0){
			for (int i=0;i<equipo.getvSoftwares().size();i++){
				lanzarInsert("EQSOFT", "(idSOFT,idEQ)", "('"+equipo.getvSoftwares().elementAt(i).getIdSoftware()+"','"+equipo.getIdEquipo()+"')");
			}
		}
	}
	
	public void modificarEquipo(Equipo equipo) throws SQLException{
		if (this.getConexion()==null){
			return;
		}
		lanzarUpdate("EQUIPOS", "idEQUIPOS='" + equipo.getIdEquipo() + "',AULA_idAULA='" + equipo.getCodAula() + "'", "idEQUIPOS='" + equipo.getIdEquipo()+"'");
		if(equipo.getvHardwares()!=null){
			for (int i=0;i<equipo.getvHardwares().size();i++){
				lanzarUpdate("EQHARD", "idHard='"+equipo.getvHardwares().elementAt(i).getIdHardware()+"',idEquipo='"+equipo.getIdEquipo()+"'","idEquipo='"+equipo.getIdEquipo()+"'");
			}
		}
		if (equipo.getvSoftwares().size()!=0 || equipo.getvSoftwares()!=null){
			if (tieneSoft(equipo)){
				for (int i=0;i<equipo.getvSoftwares().size();i++){
					lanzarUpdate("EQSOFT", "idSOFT='"+equipo.getvSoftwares().elementAt(i).getIdSoftware()+"',idEQ='"+equipo.getIdEquipo()+"'", "idEQ='"+equipo.getIdEquipo()+"'");
				}
			}else{
				for (int i=0;i<equipo.getvSoftwares().size();i++){
					lanzarInsert("EQSOFT", "(idSOFT,idEQ)", "('"+equipo.getvSoftwares().elementAt(i).getIdSoftware()+"','"+equipo.getIdEquipo()+"')");
				}
			}
		}
	}
	
	/**
	 * Devuelve true si el equipo tiene software instalado
	 * @param equipo
	 * @return
	 * @throws SQLException
	 */
	public boolean tieneSoft(Equipo equipo) throws SQLException{
		if (this.getConexion()==null){
			return false;
		}
		ResultSet rs = lanzarSelect("SELECT idSOFT FROM EQSOFT WHERE idEQ='"+equipo.getIdEquipo()+"'");
		while (rs.next()){
			return true;
		}
		return false;
	}
	
	/**
	 * Devuelve el último registro de la tabla
	 * 
	 * @param tabla El nombre de la tabla de la que se quiere obtener el último registro.
	 * @return Devuelve el último registro, si falla devuelve 0.
	 * @throws SQLException 
	 */
	public int ultimoRegistro(String tabla) throws SQLException{
		if (this.getConexion()==null){
			return 0;
		}
		int ultReg = 0;
		ResultSet rs_count = lanzarSelect("SELECT COUNT(*) FROM "+tabla);
		while (rs_count.next()){
			ultReg = rs_count.getInt(1);
		}
		return ultReg;
	}
	
	public Vector<TipoHard> obtenerTiposHardware() throws SQLException{
		if (this.getConexion()==null){
			return null;
		}
		Vector<TipoHard> vTipoHards = new Vector<TipoHard>();
		ResultSet rs_tipoHard = lanzarSelect("SELECT * FROM TIPO_HARD");
		while(rs_tipoHard.next()){
			TipoHard tipoHard = new TipoHard(rs_tipoHard.getString(1), rs_tipoHard.getString(2));
			vTipoHards.addElement(tipoHard);
		}
		return vTipoHards;
	}

	public Vector<Hardware> obtenerHardware() throws SQLException{
		if (this.getConexion()==null){
			return null;
		}
		Vector<Hardware> vHardwares = new Vector<Hardware>();
		ResultSet rs_hard = lanzarSelect("SELECT * FROM HARDWARE");
		while(rs_hard.next()){
			Hardware hardware = new Hardware(rs_hard.getString(1), rs_hard.getString(2), rs_hard.getString(3), rs_hard.getString(4));
			vHardwares.addElement(hardware);
		}
		return vHardwares;
	}
	
	public void crearHardware(Hardware hardware) throws SQLException {
		if (this.getConexion()==null){
			return;
		}
		lanzarInsert("HARDWARE", "(idHARDWARE,NOMBRE,DATOS,TIPO_HARD_idTIPO_HARD)", "('"+ hardware.getIdHardware() + 
								"','" + hardware.getNombre() + "','" + hardware.getDatos() + "','" + 
																				hardware.getTipoHardware() + "')");
	}
	
	public void borrarHardware(Hardware hardware) throws SQLException{
		if (this.getConexion()==null){
			return;
		}
		lanzarDelete("HARDWARE", "idHARDWARE='"+hardware.getIdHardware()+"'");
	}
	
	public Vector<Software> obtenerSoftware() throws SQLException{
		if (this.getConexion()==null){
			return null;
		}
		Vector<Software> vSoftwares = new Vector<Software>();
		ResultSet rs_soft = lanzarSelect("SELECT * FROM SOFTWARE");
		while(rs_soft.next()){
			Software software = new Software(rs_soft.getString(1), rs_soft.getString(2), rs_soft.getString(3));
			vSoftwares.addElement(software);
		}
		return vSoftwares;
	}
	
	public void crearSoftware(Software software) throws SQLException{
		if (this.getConexion()==null){
			return;
		}
		lanzarInsert("SOFTWARE", "(idSOFTWARE,NOMBRE,DESCRIPCION)", "('"+software.getIdSoftware()+"','"+software.getNombre()+"','"+software.getDescripcion()+"')");
	}
	
	public void borrarSoftware(Software software) throws SQLException{
		if (this.getConexion()==null){
			return;
		}
		lanzarDelete("SOFTWARE", "idSOFTWARE='"+software.getIdSoftware()+"'");
	}
	
	public Vector<Solicitud> obtenerSolicitudes() throws SQLException{
		if (this.getConexion()==null){
			return null;
		}
		Vector<Solicitud> vSolicitudes = new Vector<Solicitud>();
		ResultSet rs_sol = lanzarSelect("SELECT * FROM SOLICITUDES");
		while(rs_sol.next()){
			Equipo eq = obtenerEquipo(rs_sol.getString(5));
			Usuario usu = obtenerUsuario(rs_sol.getString(4));
			Aula aula = obtenerAula(rs_sol.getString(3));
			Software soft = obtenerSoft(rs_sol.getString(2));
			Solicitud sol = new Solicitud(rs_sol.getString(1), soft, aula, eq, usu, rs_sol.getBoolean(6), rs_sol.getString(7));
			vSolicitudes.addElement(sol);
		}
		return vSolicitudes;
	}
	
	public void crearSolicitud(Solicitud sol) throws SQLException{
		if (this.getConexion()==null){
			return;
		}
		if (sol.aula==null){
			// Para un equipo
			lanzarInsert("SOLICITUDES", "(idSOLICITUDES,idSOFT,idAULA,idUSUARIOS,idEQUIPOS,RESUELTO,OBSERVACIONES)",
							"('"+sol.getIdSolicitud()+"','"+sol.getSoftware().getIdSoftware()+"','-1','"+sol.usuario.getIdUsuario()+
							"','"+sol.equipo.getIdEquipo()+"',"+sol.isResuelto()+",'"+sol.getObservaciones()+"')");
		}else{
			// Para un aula entera
			lanzarInsert("SOLICITUDES", "(idSOLICITUDES,idSOFT,idAULA,idUSUARIOS,idEQUIPOS,RESUELTO,OBSERVACIONES)",
					"('"+sol.getIdSolicitud()+"','"+sol.getSoftware().getIdSoftware()+"','"+sol.aula.getIdAula()+"','"+
					sol.usuario.getIdUsuario()+"','-1',"+sol.isResuelto()+",'"+sol.getObservaciones()+"')");
		}
	}
	
	public void atenderSolicitud(Solicitud solicitud) throws SQLException{
		if (this.getConexion()==null){
			return;
		}
		if (solicitud.equipo.getIdEquipo().equals("-1")){
			//instalación aula entera
			for (int i=0;i<solicitud.aula.getvEquipos().size();i++){
				instalarSoftwareEquipo(solicitud.getSoftware(), solicitud.equipo);
			}
		}else{
			//instalación único equipo
			instalarSoftwareEquipo(solicitud.getSoftware(), solicitud.equipo);
		}
		lanzarUpdate("SOLICITUDES", "RESUELTO="+solicitud.isResuelto()+"", "idSOLICITUDES='"+solicitud.getIdSolicitud()+"'");
	}
	
	public void instalarSoftwareEquipo(Software software, Equipo equipo){
		if (this.getConexion()==null){
			return;
		}
		try {
			lanzarInsert("EQSOFT", "(idSOFT,idEQ)", "('"+software.getIdSoftware()+"','"+equipo.getIdEquipo()+"')");
		} catch (SQLException e) {
			//e.printStackTrace();
		}
	}
	
	public Equipo obtenerEquipo(String idEquipo) throws SQLException{
		if (this.getConexion()==null){
			return null;
		}
		Equipo equipo = null;
		ResultSet rs_eq = lanzarSelect("SELECT * FROM EQUIPOS WHERE idEQUIPOS='"+idEquipo+"'");
		while (rs_eq.next()){
			equipo = new Equipo(rs_eq.getString(1), rs_eq.getString(2));
		}
		return equipo;
	}
	
	public Usuario obtenerUsuario(String idUsuario) throws SQLException{
		if (this.getConexion()==null){
			return null;
		}
		Usuario usuario = null;
		ResultSet rs_usu = lanzarSelect("SELECT * FROM USUARIOS WHERE idUSUARIOS='"+idUsuario+"'");
		while(rs_usu.next()){
			usuario = new Usuario(rs_usu.getString(1), rs_usu.getString(2), rs_usu.getString(3), 
						rs_usu.getString(4), rs_usu.getString(6));
		}
		return usuario;
	}
	
	public Aula obtenerAula(String idAula) throws SQLException{
		if (this.getConexion()==null){
			return null;
		}
		Aula aula = null;
		Vector<Equipo> vEqAula = new Vector<Equipo>();
		ResultSet rs_aula = lanzarSelect("SELECT * FROM AULAS WHERE idAULA='"+idAula+"'");
		while (rs_aula.next()){
			ResultSet rs_aueq = lanzarSelect("SELECT * FROM EQUIPOS WHERE AULA_idAULA='"+idAula+"'");
			while(rs_aueq.next()){
				Equipo equipo = new Equipo(rs_aueq.getString(1), rs_aueq.getString(2));
				vEqAula.addElement(equipo);
			}
			aula = new Aula(rs_aula.getString(1), rs_aula.getInt(2), vEqAula);
		}
		return aula;
	}
	
	public Software obtenerSoft(String idSoftware) throws SQLException{
		if (this.getConexion()==null){
			return null;
		}
		Software soft = null;
		ResultSet rs_soft = lanzarSelect("SELECT * FROM SOFTWARE WHERE idSOFTWARE='"+idSoftware+"'");
		while(rs_soft.next()){
			soft = new Software(rs_soft.getString(1), rs_soft.getString(2), rs_soft.getString(3));
		}
		return soft;
	}
}
